#ifndef SPI
#define	SPI

#ifndef PB_CLK
#warning "PB_CLK not defined, defaulting to 80E6"
#define PB_CLK 80E6
#endif

// *****************************************************************************
// CHANGE LOG
//
// *****************************************************************************

// *****************************************************************************
// *****************************************************************************
// Section: Includes
// *****************************************************************************
// *****************************************************************************
#include <p32xxxx.h>
#include <plib.h>
#include <string>

// *****************************************************************************
// *****************************************************************************
// Section: Constants & Data Types
// *****************************************************************************
// *****************************************************************************

/*! \brief Allows reading and writing to a SPI interface
 */
class Spi
{
  public:

	/*! \brief Where in clock to sample data
	 */
	enum class SampleLocation
	{
		Middle = 0, /*!< Send data in midle of clock */
				End = SPI_CONFIG_SMP_END /*!< Send data at end of clock */

	};

	// Static Methods
	static void Initialize(
					SpiChannel channel,
					UINT32 clockSpeed,
					SampleLocation sampleLocation);

	static void Close(SpiChannel channel);

	// Constructors
	Spi(SpiChannel channel, IoPortId csPort, UINT32 pin);
	Spi();

	// Destructor
	virtual ~Spi();

	// Methods
	virtual void Write(unsigned char data);
	virtual void Write(const unsigned char *buffer, int length);
	virtual void Write(const unsigned char *buffer, int index, int length);
	virtual void Write(std::string data);

	virtual unsigned char Read();
	virtual void Read(unsigned char *buffer, int length);
	virtual void Read(std::string *buffer);
	virtual void Read(std::string *buffer, int length);

	virtual void ChipSelect(bool selected);

	virtual void SetConfiguration(SpiChannel channel, IoPortId csPort, UINT32 pin);

	virtual void Close();
	virtual bool IsOpen();


  private:
	SpiChannel _spiChannel;
	IoPortId _csPort;
	UINT32 _pin;
	bool _isOpen;
};

#endif

